package com.cross.excel;

import java.io.File;
import java.io.IOException;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableCell;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

import com.cross.core.AbstractWriter;
import com.cross.core.Column;
import com.cross.core.Header;
import com.cross.core.Item;
import com.cross.core.Row;
import com.cross.exception.FileValidatorException;
import com.cross.util.Constant;
import com.cross.util.FileUtil;
import com.cross.util.StringUtils;

public class SimpleExcelWriter extends AbstractWriter {
	
	private WritableWorkbook book;
	
	private int bookSize;
	
	private File temp;
	
	private int sheetIndex = 0;
	
	private WritableSheet sheet;
	
	public SimpleExcelWriter() throws Exception{
		
	}
	
	public SimpleExcelWriter(Header header, String file) throws Exception{
		if (StringUtils.isEmpty(file)) {
			throw new FileValidatorException("文件名不能为空");
		}
		File temp = new File(file);

		if(!temp.exists()){
			temp.createNewFile();
			Workbook.createWorkbook(temp);
		}
		if(!temp.isFile()){
			throw new FileValidatorException("请选择一个文件");
		}
		super.setHeader(header);
		init(temp);
	}

	public SimpleExcelWriter(Header header, File file) throws Exception{
		if (null == file) {
			throw new FileValidatorException("文件不存在.");
		}
		setHeader(header);
		init(file);
	}
	
	public SimpleExcelWriter(Header header, WritableWorkbook book){
		if (book == null) {
			throw new RuntimeException("文件中没有任何工作薄");
		}
		this.book = book;
		super.setHeader(header);
		bookSize = book.getNumberOfSheets();
		nextSheet();
	}
	
	private void init(File file) throws Exception {
		book = getWorkbook(file);
		if (book == null) {
			throw new FileValidatorException("文件中没有任何工作薄");
		}
		bookSize = book.getNumberOfSheets();
		nextSheet();
	}

	private WritableWorkbook getWorkbook(File file) throws Exception {
		try {
			synchronized (this){
				temp = File.createTempFile("cross_"+System.currentTimeMillis(), ".xls");
			}
			FileUtil.copy(file, temp);
			// 打开Excel模板
			Workbook template = Workbook.getWorkbook(temp);
			// 装载模板
			return Workbook.createWorkbook(file, template);
		} catch (Exception e) {
			throw e;
		}
	}
	
	protected void writeRow(){
		currentRowIndex++;
		if(currentRowIndex>Constant.SHEETSIZT){
			nextSheet();
		}
		writeRow(currentRow);
		totalRow++;
	}
	
	private void writeHeader(Header header){
		sheet.setName(header.getObjectName()+"-"+sheetIndex);
		currentRowIndex = 0;
		WritableCell[] cells = createCell(header);
		for(WritableCell c : cells){
			try {
				sheet.addCell(c);
			} catch (RowsExceededException e) {
				e.printStackTrace();
			} catch (WriteException e) {
				e.printStackTrace();
			}
		}
		currentRowIndex++;
		cells = createStructCell(header);
		for(WritableCell c : cells){
			try {
				sheet.addCell(c);
			} catch (RowsExceededException e) {
				e.printStackTrace();
			} catch (WriteException e) {
				e.printStackTrace();
			}
		}
		currentRowIndex++;
	}
	
	private boolean writeRow(Row row){
		WritableCell[] cells = toCells(row);
		for(WritableCell c : cells){
			try {
				sheet.addCell(c);
			} catch (RowsExceededException e) {
				return false;
			} catch (WriteException e) {
				return false;
			}
		}
		return true;
	}
	private WritableCell[] createCell(Header header){
		WritableCell[] cells = new WritableCell[header.size()];
		int index = 0;
		for(Column column : header.getColumns()){
			cells[index] = toCell(column,index);
			index++;
		}
		return cells;
	}
	
	private WritableCell[] createStructCell(Header header){
		WritableCell[] cells = new WritableCell[header.size()];
		int index = 0;
		for(Column column : header.getColumns()){
			cells[index] = toStruct(column,index);
			index++;
		}
		return cells;
	}
	
	private WritableCell[] toCells(Row row){
		WritableCell[] cells = new WritableCell[row.size()];
		int index = 0;
		for(Item item : row.getItems()){
			cells[index] = toCell(item,index);
			index++;
		}
		return cells;
	}
	
	private WritableCell toCell(Column column, int index){
		WritableCell cell = new Label(index, (int)currentRowIndex, column.getTitle());
		return cell;
	}
	
	private WritableCell toStruct(Column column, int index){
		WritableCell cell = new Label(index, (int)currentRowIndex, 
				column.getType()+","+column.getPrecision()+","+column.isVariable().toString());
		return cell;
	}
	
	private WritableCell toCell(Item item, int index){
		WritableCell cell = new Label(index, (int)currentRowIndex, item.get().toString());
		return cell;
	}
	
	private boolean nextSheet(){
		sheet = getSheet();
		currentRowIndex = 0;
		writeHeader(header);
		return true;
	}
	
	private WritableSheet getSheet(){
		if(sheetIndex>=bookSize){
			bookSize++;
			WritableSheet sheet = book.createSheet(header.getObjectName()+"-"+System.currentTimeMillis(), bookSize);
			sheetIndex++;
			return sheet;
		} else {
			WritableSheet sheet = book.getSheet(sheetIndex++);
			return sheet;
		}
	}
	
	
	@Override
	public void close() {
		try {
			book.write();
			book.close();
		} catch (WriteException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			temp.delete();
		}
	}
}
